* run-all.do
* Rui Yu
* December 7th, 2025

* Run analysis from clean, merged datas

clear all
clear matrix
clear mata
matrix drop _all
capture file close _all
capture log close

global log_path ".`c(dirsep)'output`c(dirsep)'"
log using "${log_path}run-all.log", replace text

set more off
set matsize 11000
set maxvar 30000
set emptycells drop
set seed 19911106

global bin_num 20

* Set paths
global code_path ".`c(dirsep)'codes"
global in_path ".`c(dirsep)'data"
global out_path ".`c(dirsep)'output"
global temp_path ".`c(dirsep)'supplement"

global if_cond "if analysis_sample == 1 & ((ap_sl_cs==1 | ap_sl_cr==1)) & network_node_N < 50"

******************************************
*Define main program. This is what runs. *
******************************************

capture program drop main
program define main

	run_table_1

	run_table_2

	run_figure_1

	run_figure_2

	run_table_3

	run_table_4

	run_figure_3

	run_table_5

end

capture program drop run_table_1
program define run_table_1

	use "${in_path}`c(dirsep)'donor-election_developer-rd.dta", clear

	* Generate contribution recipient category
	gen recipient = "Winner"    if (contributionamt1 > 0 & !mi(contributionamt1)) ///
	                             & (mi(contributionamt2) | contributionamt2 <= 0)

	replace recipient = "Runner-up" if (contributionamt2 > 0 & !mi(contributionamt2)) ///
	                                 & (mi(contributionamt1) | contributionamt1 <= 0)

	replace recipient = "Both"      if (contributionamt2 > 0 & !mi(contributionamt2)) ///
	                                 & (contributionamt1 > 0 & !mi(contributionamt1))

	gen tmp = !mi(recipient)

	label variable recipient "Contributing Developers by Mayoral Candidate"
	label variable tmp       "Contributing Developers"

	label def tmp 1 " "
	label value tmp tmp

	tabout tmp recipient if tmp==1 & analysis_sample == 1 ///
	    using ${out_path}`c(dirsep)'tables`c(dirsep)'table_1_firm.tex,  ///
	    c(count tot_cn ///
	      mean tot_cn sd tot_cn ///
	      mean tot_sl_unt_res sd tot_sl_unt_res ///
	      mean tot_sl_val_res sd tot_sl_val_res) ///
	    sum ///
	    h1(Summary Statistics on Developer Contributions to Mayoral Candidates) ///
	    h2(_ Contribution_Amount Housing_Units_Sold Housing_Sales) h2c(1 2 2 2) ///
	    clab(Count Mean SD Mean SD Mean SD) ///
	    font(italic) f(0c 1cm 1cm 1c 1c 1cm 1cm) replace style(tex) label ///
	    fn("Displayed are tabulations and summary statistics ...") replace ///
	    twidth(23) ptotal(none) ntc noborder ///
	    pretext("\documentclass[12pt]{article}\n\usepackage{setspace}\n\begin{document}\n\doublespacing\n") ///
	    posttext("\n\end{document}")

	* --------------------------------------------- *
	* Load data for summary table
	* --------------------------------------------- *
	use "${in_path}`c(dirsep)'election_rd.dta", clear

	* Create election_id if not already present
	capture confirm variable election_id
	if _rc != 0 {
	    gegen election_id = group(election_state election_year election_city)
	}

	* --------------------------------------------- *
	* Variables & labels needed for summary table
	* --------------------------------------------- *

	* Single row category for Mayors
	gen tmp = 1
	label variable tmp "Mayors"
	label def tmp 1 " "
	label value tmp tmp

	* Column classification: mayor support
	label variable D_sh_cn_ac_cst "Mayors by Developer Support"
	label def D_sh_cn_ac_cst ///
	    1 "Pro-Development" ///
	    0 "Non-Development"
	label value D_sh_cn_ac_cst D_sh_cn_ac_cst

	* Scaled variables used in table
	gen sh_cn_wn_cst_1_hd = sh_cn_wn_cst_1 * 100
	gen cn1_th            = cn1 / 1000

	* --------------------------------------------- *
	* Produce Summary Table
	* --------------------------------------------- *

	tabout tmp D_sh_cn_ac_cst ///
	    if !missing(D_sh_cn_ac_cst) ///
	    using ${out_path}`c(dirsep)'tables`c(dirsep)'table_1_city.tex, ///
	    sum c( count tmp ///
	           mean cn1 sd cn1 ///
	           mean sh_cn_wn_cst_1_hd sd sh_cn_wn_cst_1_hd ///
	           mean ptotalunits sd ptotalunits ) ///
	    h1(Summary Statistics on Mayors) ///
	    h2(_ Contributions_from_Developers ///
	       Share_from_Developers Housing_Permits_Issued) ///
	    h2c(1 2 2 2) ///
	    clab(Count Mean SD Mean SD Mean SD) ///
	    f(0c 1cm 1cm 1p 1p 1c 1c) ///
	    replace style(tex) label note("") twidth(14) font(italic) ///
	    longtable ptotal(none) noborder ntc


end

capture program drop run_table_2
program define run_table_2

    * ----------------------------------------------------------
    * Load analysis dataset
    * ----------------------------------------------------------
    use "${in_path}`c(dirsep)'donor-election_developer-rd.dta", clear

    * ----------------------------------------------------------
    * Create election fixed effects if not already present
    * ----------------------------------------------------------
    capture confirm variable election_fe_1
    if _rc != 0 quietly tab election_id, gen(election_fe_)

    local m_list 1 2
    local model_label ""

    foreach m in `m_list' {

        local cluster election_id
        local cluster_lab "ELECTION"

        * ------------------------------------------------------
        * Dependent variable
        * ------------------------------------------------------
        if `m' == 1 local dep_var ch_tot_sl_unt_res
        if `m' == 2 local dep_var th_ch_tot_sl_val_res

        * ------------------------------------------------------
        * FE controls
        * ------------------------------------------------------
        local covs covs(election_fe_*)
        local cont_lab "Election FE"

        * ------------------------------------------------------
        * Label collection
        * ------------------------------------------------------
        local lab: variable label `dep_var'
        if "`lab'" == "" local lab `dep_var'
        if `m'==1 local model_label "`"`lab'"'"
        else       local model_label `" `model_label' `"`lab'"' "'

        * ------------------------------------------------------
        * Clear stored e()
        * ------------------------------------------------------
        ereturn clear

        * ------------------------------------------------------
        * Bandwidth selection (only needed if FE present)
        * ------------------------------------------------------
        local bw
        local bs
        local poly_order
        if strpos("`covs'", "_fe_") {
            rdbwselect `dep_var' MV $if_cond, vce(cluster `cluster') masspoints(off)
            local bw h(`e(h_mserd)')
            local bs b(`e(b_mserd)')
            local poly_order p(`e(p)')
        }

        * ------------------------------------------------------
        * Main RD run
        * ------------------------------------------------------
        rdrobust `dep_var' MV $if_cond, vce(cluster `cluster') `bw' `bs' `poly_order' `covs' masspoints(off)

        * ------------------------------------------------------
        * Store coefficient
        * ------------------------------------------------------
        matrix betass = e(b)
        matrix colnames betass = "Pro-Mayor"
        erepost b = betass, rename
        eststo reg_`m'

        * ------------------------------------------------------
        * Robust p-value
        * ------------------------------------------------------
        local robp: di %10.3fc `e(pv_rb)'

        * ------------------------------------------------------
        * Dependent variable mean
        * ------------------------------------------------------
        calc_dep_mean `dep_var' $if_cond
        local out_mean = r(out_mean)

        * ------------------------------------------------------
        * Number of donors and elections within bandwidth
        * ------------------------------------------------------
        quietly distinct election_id firm_id $if_cond & e(sample)==1 & abs(MV)<=e(h_l), joint
        local contributor_N: di %10.0fc r(ndistinct)

        quietly distinct election_id $if_cond & e(sample)==1 & abs(MV)<=e(h_l), joint
        local election_N: di %10.0fc r(ndistinct)

        * ------------------------------------------------------
        * Bandwidth label for table
        * ------------------------------------------------------
        local mv_window_lab = e(h_l)*100
        local mv_window_lab: di %10.1fc `mv_window_lab'

        * ------------------------------------------------------
        * Attach table statistics
        * ------------------------------------------------------
        estadd local list_dep_mean "`out_mean'"
        estadd local list_mv_window "`mv_window_lab'\%"
        estadd local list_eff_N "`contributor_N'"
        estadd local list_ele_N "`election_N'"
        estadd local list_robp `robp'
        estadd local list_cluster `cluster_lab'
        estadd local list_control `cont_lab'
        estadd local list_poly_order `e(p)'
        estadd local list_kernel `e(kernel)'
    }

    * ----------------------------------------------------------
    * Export table
    * ----------------------------------------------------------
    esttab reg_* ///
        using ${out_path}`c(dirsep)'tables`c(dirsep)'table_2.tex, ///
        mgroups(`model_label', pattern(1 1) ///
            prefix(\multicolumn{@span}{c}{) suffix(}) span) ///
        replace r2 se compress star(* 0.1 ** 0.05 *** 0.01) ///
        nomtitles label nonotes ///
        s(list_dep_mean list_robp list_mv_window list_eff_N list_ele_N, ///
            label("Dep. Var. Mean" "Rob. P-Value" "Optimal Bandwidth" ///
                  "Donors within Bandwidth" "Elections within Bandwidth"))
end

capture program drop run_figure_1
program define run_figure_1

	* ----------------------------------------------------------
	* Load pre-filtered RD dataset
	* ----------------------------------------------------------
	use "${in_path}`c(dirsep)'donor-election_developer-rd.dta", clear

	* ----------------------------------------------------------
	* Create election fixed effects if not already present
	* ----------------------------------------------------------
	capture confirm variable election_fe_1
	if _rc != 0 {
	    quietly tab election_id, gen(election_fe_)
	}

	* ----------------------------------------------------------
	* Prepare covariates list for rdplot
	* ----------------------------------------------------------
	ds election_fe_*
	local cov_list `r(varlist)'
	local covs covs(`cov_list')

	* ----------------------------------------------------------
	* Set dependent variable and cluster
	* ----------------------------------------------------------
	local dep_var ch_tot_sl_unt_res
	local cluster election_id
	local graph_name graph_`dep_var'

	* ----------------------------------------------------------
	* Ensure constant for residualization
	* ----------------------------------------------------------
	capture confirm variable tmp_const
	if _rc != 0 gen tmp_const = 1

	* ----------------------------------------------------------
	* Residualize outcome
	* ----------------------------------------------------------
	capture confirm variable r_`dep_var'
	if _rc != 0 {
	    quietly reghdfe `dep_var' tmp_const $if_cond, absorb(election_id) residuals(r_`dep_var')
	}

	* ----------------------------------------------------------
	* Bandwidth selection
	* ----------------------------------------------------------
	rdbwselect `dep_var' MV $if_cond, vce(cluster `cluster') masspoints(off)
	local est_bw = e(h_mserd)
	local bw h(`est_bw')
	local bs b(`e(b_mserd)')
	local poly_order p(`e(p)')

	* ----------------------------------------------------------
	* RD plot to get fitted values
	* ----------------------------------------------------------
	rdplot r_`dep_var' MV $if_cond & abs(MV)<=0.2, ///
	    `covs' binselect(qspr) `bw' `bs' `poly_order' masspoints(off) ///
	    graph_options(legend(off) name(`graph_name', replace)) genvars

	* ----------------------------------------------------------
	* Compute MSE and confidence intervals
	* ----------------------------------------------------------
	gen tmp_error_sq = (r_`dep_var' - rdplot_hat_y)^2
	gegen mse = mean(tmp_error_sq)
	gegen mean_x = mean(MV)
	gen tmp_x_err_sq = (MV - mean_x)^2
	gegen tmp_sum_x_err_sq = sum(tmp_x_err_sq)
	gen tmp_N = e(N_l) + e(N_r)
	gen se_yx = sqrt(mse*(1/tmp_N + (tmp_x_err_sq/tmp_sum_x_err_sq)))
	gen ci_ub = rdplot_hat_y + 1.96*se_yx
	gen ci_lb = rdplot_hat_y - 1.96*se_yx
	bys rdplot_id: gen tmp_1 = _n

	* ----------------------------------------------------------
	* Plot parameters
	* ----------------------------------------------------------
	local y_max = 3
	local y_int = 1
	local y_min = -3
	local y_lab_loc = `y_max'*1.15
	local fig_cond "if abs(MV)<=`est_bw'"

	* ----------------------------------------------------------
	* Final RD figure
	* ----------------------------------------------------------
	twoway ///
	    (line rdplot_hat_y MV `fig_cond' & MV>=0, sort lpattern(solid) lwidth(vthick) lcolor(black)) ///
	    (line rdplot_hat_y MV `fig_cond' & MV<0,  sort lpattern(solid) lwidth(vthick) lcolor(black)) ///
	    (scatter rdplot_mean_y rdplot_mean_x $if_cond & tmp_1==1 & abs(MV)<=0.2, sort msymbol(Oh) mcolor(black) msize(medlarge)), ///
	    legend(off) name(`graph_name', replace) ///
	    xtitle("Margin of Victory in Mayoral Election", size(medlarge)) ///
	    xline(0) ///
	    xlabel(-0.2 "-20%" -0.1 "-10%" 0 "0%" 0.1 "10%" 0.2 "20%", labsize(medlarge)) ///
	    ylabel(`y_min'(`y_int')`y_max', format(%9.3gc) labsize(medlarge)) ///
	    yscale(range(`y_min' `y_max')) ///
	    title(" ", size(medlarge)) ///
	    text(`y_max' 0 "Firms Supporting Mayor {&rarr}", size(medlarge) placement(se)) ///
	    text(`y_max' -0.003 "{&larr} Firms Supporting Runner-Up", size(medlarge) placement(sw) justification(right)) ///
	    text(`y_lab_loc' -0.23 "New Housing Units Sold", size(medlarge) placement(ne) justification(right)) ///
	    ysize(10) xsize(16)

	* ----------------------------------------------------------
	* Export figure
	* ----------------------------------------------------------
	graph export "${out_path}`c(dirsep)'figures`c(dirsep)'figure_1.pdf", as(pdf) replace


end // end of program run_figure_1

capture program drop run_figure_2
program define run_figure_2

    * ----------------------------------------------------------
    * Heterogeneity RD Estimate: City Council Approval Required
    * ----------------------------------------------------------

    * Load dataset
    use "${in_path}`c(dirsep)'donor-election_developer-rd.dta", clear

    * Create election fixed effects if not present
    capture confirm variable election_fe_1
    if _rc != 0 quietly tab election_id, gen(election_fe_)

    * Set dependent variable
    local dep_var ch_tot_sl_unt_res

    * Cluster and covariates
    local cluster election_id
    local covs covs(election_fe_*)

    * Heterogeneity: council_byright
    gen no_council_byright = ~council_byright
    local heterog no_council_byright
    local lab "RD Estimates by Subsamples"

    * ----------------------------------------------------------
    * Run RD for het = 0 (Not Needed) and het = 1 (Required)
    * ----------------------------------------------------------
    foreach set in 0 1 {
        if `set'==0 local cond "${if_cond} & `heterog'==0"
        if `set'==1 local cond "${if_cond} & `heterog'==1"

        * Bandwidth selection
        rdbwselect `dep_var' MV `cond', vce(cluster `cluster') masspoints(off)
        local bw h(`e(h_mserd)')
        local bs b(`e(b_mserd)')
        local poly_order p(`e(p)')

        * Run RDROBUST
        rdrobust `dep_var' MV `cond', vce(cluster `cluster') ///
            `bw' `bs' `poly_order' `covs' masspoints(off)

        * ------------------------------------------------------
        * Dynamically rename coefficient to match original x-axis
        * ------------------------------------------------------
        tempname V
        matrix `V' = e(V)
        matrix `V'[1,1] = e(se_tau_rb)^2
        erepost V=`V'

        matrix betass = e(b)
        matrix colnames betass = "`lab'"   // Sets x-axis label
        erepost b = betass, rename

        * Store estimates
        eststo reg_`set'_`heterog'
    }

    * ----------------------------------------------------------
    * Plot coefficients (Not Needed first, Required second)
    * ----------------------------------------------------------
    local graph_name Fig_`dep_var'

    coefplot ///
        (reg_1_`heterog', label("City Council Approval Not Needed") msize(medlarge) msymbol(O) ///
            ciopts(recast(rcap) lwidth(thick))) ///
        (reg_0_`heterog', label("City Council Approval Required") msize(medlarge) mcolor(gs16) mlcolor(gs10) ///
            mlwidth(medthick) msymbol(O) ciopts(recast(rcap) lwidth(thick) lcolor(gs10))), ///
        ciopts(recast(rcap) lwidth(thick)) vertical ///
        msize(medlarge) ///
        mlabel(cond(@pval<.01, "***", cond(@pval<.05, "**", cond(@pval<.1,"*", "")))) ///
        xtitle(, size(medlarge)) ytitle(, size(medlarge)) ///
        title("", size(medlarge)) yline(0) xsize(10) ///
        text(8.5 0.42 "New Housing Units Sold", size(medlarge) placement(ne) justification(right)) ///
        name(`graph_name', replace) ///
        ylabel(, format(%8.0gc) labsize(medlarge)) ///
        graphregion(margin(2 4 2 2)) ///
        legend( ///
            ring(0) pos(2) rows(2) ///
            subtitle("City Council Role in By-Right Developments", size(medlarge)) ///
            region(fcolor(none)) ///
            size(medlarge) ///
        ) ///
        coeflabels(, labsize(medlarge))

    * Combine graph (layout identical to original)
    graph combine `graph_name', cols(1) rows(1) title("", size(medlarge)) ///
        note("") ysize(10) xsize(16)

    * Export plot
    graph export "${out_path}`c(dirsep)'figures`c(dirsep)'figure_2.pdf", as(pdf) replace

    * Clear estimates
    eststo clear

end

capture program drop run_table_3
program define run_table_3

    * ----------------------------------------------------------
    * Import cleaned zip–election–year DID dataset
    * ----------------------------------------------------------
    use "${in_path}`c(dirsep)'zip-election-year-did.dta", clear

    * ----------------------------------------------------------
    * Sample restriction
    * ----------------------------------------------------------
    local cond "if ((ap_sl_cs==1 | ap_sl_cr==1)) & period>=6 & period<=15"

    * ----------------------------------------------------------
    * Labels
    * ----------------------------------------------------------
    label variable pro_may_ind_post "Connected Zip \times \text{Post}"
    label variable pro_may_ind      "Connected Zip"
    label variable tot_sl_unt_res   "New Housing Units Sold in Zip"

    * ----------------------------------------------------------
    * Estimation for single outcome variable
    * ----------------------------------------------------------
    local dep_var tot_sl_unt_res
    local num = 1

    * Set model label using original logic
    local lab: variable label `dep_var'
    if "`lab'" == "" {
        local lab `dep_var'
    }
    if `num'==1 {
        local model_label "`"`lab'"'"
    }

    * Loop over FE specifications
    foreach m in 1 2 3 4 {

        local cluster     city_id
        local cluster_lab "CITY"
        local fe          period_id zip_id
        local fe_lab      ""Period, Zip""

        if `m'==2 {
            local fe     period_id city_id
            local fe_lab ""Period, City""
        }
        if `m'==3 {
            local fe     period_id city_id year
            local fe_lab ""Period, City, Year""
        }
        if `m'==4 {
            local fe     period_id city_id##year
            local fe_lab ""Period, Zip, City \times \text{Year}""
        }

        * Run regression
        eststo est_`dep_var'_`m': ///
            reghdfe `dep_var' pro_may_ind_post pro_may_ind Post ///
            `cond', absorb(`fe') vce(cluster `cluster')

        * --------------------------------------------------
        * Dependent variable mean
        * --------------------------------------------------
        local base_dep_var = subinstr(subinstr("`dep_var'", "fh_", "",.), "th_", "",.)
        summ `base_dep_var' if e(sample)==1 & period==10

        if strpos("`dep_var'","th_") {
            local out_mean = `r(mean)'/1000
        }
        else {
            local out_mean = `r(mean)'
        }
        local out_mean: di %10.2fc `out_mean'

        * --------------------------------------------------
        * Sample statistics
        * --------------------------------------------------
        quietly count if e(sample)==1
        local panel_N: di %10.0fc `r(N)'

        quietly gdistinct election_id zip_id if e(sample)==1, joint
        local Zip_N: di %10.0fc r(ndistinct)

        quietly gdistinct election_id if e(sample)==1, joint
        local election_N: di %10.0fc r(ndistinct)

        * Store table stats
        quietly estadd local list_dep_mean "`out_mean'"
        quietly estadd local list_panel_N  "`panel_N'"
        quietly estadd local list_zip_N    "`Zip_N'"
        quietly estadd local list_ele_N    "`election_N'"
        quietly estadd local list_cluster  `cluster_lab'
        quietly estadd local list_fe       `fe_lab'
    }

    * ----------------------------------------------------------
    * Table output
    * ----------------------------------------------------------
    esttab est* ///
        using ${out_path}`c(dirsep)'tables`c(dirsep)'table_3.tex, ///
        keep(pro_may_ind_post) ///
        mgroups(`model_label', pattern(1 0 0 0) ///
            prefix(\multicolumn{@span}{c}{) suffix(}) span) ///
        replace r2 se compress star(* 0.1 ** 0.05 *** 0.01) ///
        nomtitles label nonotes ///
        s(list_dep_mean list_fe list_zip_N list_ele_N, ///
            label("Dep. Var. Mean" "Fixed Effects" "Zip Codes" "Mayoral Elections")) ///
        addnote("") ///
        interaction(" $\times$ ")

end

capture program drop run_table_4
program define run_table_4

    * ----------------------------------------------------------
	* Import city-level RD dataset
	* ----------------------------------------------------------
	use "${in_path}`c(dirsep)'election_rd.dta", clear

	* ----------------------------------------------------------
	* Sample restriction and FE setup
	* ----------------------------------------------------------
	gen _const = 1
	local cond "if sample_firm_rd==1" 

	* CBSA FE
	quietly: tab cbsa_id, gen(cbsa_fe_)
	local covs covs(cbsa_fe_*)
	local cont_lab "CBSA FE"
	local cluster "cluster cbsa_id"
	local cluster_lab "CBSA"

	* ----------------------------------------------------------
	* Labels
	* ----------------------------------------------------------
	label variable tot_sl_unt_res "New Housing Units Sold, Citywide"
	label variable const1 "Developer Donors"

	* ----------------------------------------------------------
	* Loop over dependent variables
	* ----------------------------------------------------------
	local dep_vars const1 tot_sl_unt_res ptotalunits 
	local model_label ""
	eststo clear

	local coef_tot_sl_unt_res .
	local coef_ptotalunits .

	foreach dep_var of local dep_vars {

	    * Set model label using original logic
	    local lab: variable label `dep_var'
	    if "`lab'" == "" local lab `dep_var'
	    local model_label `" `model_label' `"`lab'"'"'

	    * ------------------------------------------------------
	    * Run RD regression
	    * ------------------------------------------------------
	    rdrobust `dep_var' MV_sh_cn_ac_cst `cond', vce(`cluster') `covs'
	    
	    * Store coefficient for table
	    matrix betass = e(b)
	    matrix colnames betass = "Pro-Dev"
	    erepost b = betass, rename

	    * Capture coefficients as locals
	    if "`dep_var'" == "const1" {
	        matrix b = e(b)
	        local Ndiff = b[1,1]
	        local Ndiff_fmt: display %10.2f `Ndiff'
	    }

	    if "`dep_var'" == "tot_sl_unt_res" {
	        matrix b = e(b)
	        local coef_tot_sl_unt_res = b[1,1]

		}

	    if "`dep_var'" == "ptotalunits" {
	        matrix b = e(b)
	        local coef_ptotalunits = b[1,1]
	        eststo r_`dep_var'

        	* ----------------------------------------------------------
			* Compute Permit/Sales Ratio lambda
			* ----------------------------------------------------------
			local lambda_ratio = `coef_tot_sl_unt_res'/`coef_ptotalunits'
			local lambda_ratio_fmt: display %10.2f `lambda_ratio'
	        
	        * Attach formatted Ndiff coefficient
	        estadd local Ndiff `Ndiff_fmt'
	        estadd local PermitSalesRatio `lambda_ratio_fmt'
	    }

	    * ------------------------------------------------------
	    * Dependent variable mean
	    * ------------------------------------------------------
	    local base_dep_var = subinstr(subinstr("`dep_var'", "fh_", "",.), "th_", "",.)
	    summ `base_dep_var' if e(sample)==1 & abs(MV_sh_cn_ac_cst) <= e(h_r)

	    if strpos("`dep_var'","th_") {
	        local out_mean = `r(mean)'/1000
	    }
	    else local out_mean = `r(mean)'
	    local out_mean: di %10.2fc `out_mean'

	    * ------------------------------------------------------
	    * Count elections within bandwidth
	    * ------------------------------------------------------
	    quietly: distinct election_id if e(sample)==1 & abs(MV_sh_cn_ac_cst) <= e(h_r)
	    local election_N: di %10.0fc r(ndistinct)

	    * Record optimal bandwidth and robust p-value
	    local mv_window_lab = e(h_l)*100
	    local mv_window_lab: di %10.1fc `mv_window_lab'
	    local robp: di %10.3fc `e(pv_rb)'

	    * ------------------------------------------------------
	    * Add locals for esttab
	    * ------------------------------------------------------
	    quietly: estadd local list_dep_mean "`out_mean'"
	    quietly: estadd local list_mv_window "`mv_window_lab'\%"
	    quietly: estadd local list_ele_N "`election_N'"
	    quietly: estadd local list_poly_order `e(p)'
	    quietly: estadd local list_kernel `e(kernel)'
	    quietly: estadd local list_cluster `cluster_lab'
	    quietly: estadd local list_control `cont_lab'
	    quietly: estadd local list_robp `robp'
	}

	* ----------------------------------------------------------
	* Table output
	* ----------------------------------------------------------
	esttab r_* ///
	    using ${out_path}`c(dirsep)'tables`c(dirsep)'table_4.tex, ///
	    mgroups("Housing Permits", pattern(1) ///
	        prefix(\multicolumn{@span}{c}{) suffix(}) span) ///
	    replace r2 se compress star(* 0.1 ** 0.05 *** 0.01) ///
	    nomtitles label nonotes ///
	    s(list_dep_mean list_robp list_mv_window list_ele_N Ndiff PermitSalesRatio, ///
	      label("Dep. Var. Mean" "Rob. P-value" "Optimal Bandwidth" "Elections within Bandwidth" "{\$N^{DEV}-N^{NON}\$}" "Permit/Sales Ratio ($\lambda$)")) ///
	    addnote("")

end

capture program drop run_figure_3
program define run_figure_3

    *-----------------------------------------------
    * Load slimmed election-level data
    *-----------------------------------------------
    use "$in_path`c(dirsep)'election_rd.dta", clear

    *-----------------------------------------------
    * Ensure CBSA FE exists
    *-----------------------------------------------
    capture confirm variable cbsa_fe_1
    if _rc != 0 {
        quietly: tab cbsa_id, gen(cbsa_fe_)
    }
    local covs covs(cbsa_fe_*)

    *-----------------------------------------------
    * Ensure sample indicator exists
    *-----------------------------------------------
    capture confirm variable sample_firm_rd
    if _rc {
        gen sample_firm_rd = 1
    }

    *-----------------------------------------------
    * Generate residuals for plotting
    *-----------------------------------------------
    local dep_var ptotalunits
    capture confirm variable r_`dep_var'
    if _rc != 0 {
        gen tmp_const = 1
        quietly: reghdfe `dep_var' tmp_const, absorb(cbsa_id) residuals(r_`dep_var')
    }

    *-----------------------------------------------
    * Run RD estimate (covariates included if available)
    *-----------------------------------------------
    local cond "if sample_firm_rd==1"
    local cluster "cluster cbsa_id"

    local cmd "rdrobust `dep_var' MV_sh_cn_ac_cst `cond', vce(`cluster') `covs'"
    di "`cmd'"
    `cmd'

    local est_bw = `e(h_l)'
    local bw h(`est_bw')
    local bs b(`e(b_l)')
    local poly_order p(`e(p)')

    *-----------------------------------------------
    * Set plot parameters
    *-----------------------------------------------
    local y_max = 5000
    local y_min = -5000
    local y_int = 2500
    local y_lab_loc = `y_max'*1.15
    local lab_title: variable label `dep_var'
    local graph_name graph_`dep_var'

	local fig_cond "`cond' & abs(MV_sh_cn_ac_cst )<=`est_bw'"

    *-----------------------------------------------
    * Generate RD plot
    *-----------------------------------------------
    rdplot r_`dep_var' MV_sh_cn_ac_cst `cond', ///
        binselect(qsmvpr) `covs' `bw' `bs' `poly_order' ///
        graph_options(legend(off) ///
            title("`lab_title'", size(large)) ///
            xtitle("Margin of Victory of Pro-Dev Mayor", size(large)) ///
            xlabel(, format(%9.3gc) labsize(large)) ///
            yscale(range(`y_min' `y_max')) ///
            ylabel(`y_min'(`y_int')`y_max', format(%9.3gc) labsize(large)) ///
            name(`graph_name', replace)) genvars

    *-----------------------------------------------
    * Compute SE bands manually
    *-----------------------------------------------
    gen tmp_error_sq = (r_`dep_var' - rdplot_hat_y)^2
    gegen mse = mean(tmp_error_sq)
    gegen mean_x = mean(MV_sh_cn_ac_cst)
    gen tmp_x_err_sq = (MV_sh_cn_ac_cst - mean_x)^2
    gegen tmp_sum_x_err_sq = sum(tmp_x_err_sq)
    gen tmp_N = e(N_l) + e(N_r)
    gen se_yx = sqrt(mse * (1/tmp_N + (tmp_x_err_sq / tmp_sum_x_err_sq)))
    gen ci_ub = rdplot_hat_y + 1.96 * se_yx
    gen ci_lb = rdplot_hat_y - 1.96 * se_yx
    bys rdplot_id: gen tmp_1 = _n

    *-----------------------------------------------
    * Plot
    *-----------------------------------------------
    twoway ///
        (line rdplot_hat_y MV_sh_cn_ac_cst `fig_cond' & MV_sh_cn_ac_cst >=0, ///
            sort lpattern(solid) lwidth(vthick) lcolor(black)) ///
        (line rdplot_hat_y MV_sh_cn_ac_cst `fig_cond' & MV_sh_cn_ac_cst <0, ///
            sort lpattern(solid) lwidth(vthick) lcolor(black)) ///
        (scatter rdplot_mean_y rdplot_mean_x `cond' & tmp_1==1 & abs(MV_sh_cn_ac_cst) <= 0.1, ///
            sort msymbol(Oh) mcolor(black) msize(medlarge)), ///
        legend(off) name(`graph_name', replace) ///
        xtitle("Margin of Victory of Pro-Dev Mayor", size(medlarge)) ///
        xlabel(-0.1 "-10%" -0.05 "-5%" 0 "0%" 0.05 "5%" 0.1 "10%", labsize(medlarge)) ///
        xline(0) xlabel(, labsize(medlarge)) ///
        title(" ", size(medlarge)) ///
        ylabel(`y_min'(`y_int')`y_max', format(%9.3gc) labsize(medlarge)) ///
        yscale(range(`y_min' `y_max')) ///
        text(`y_max' 0 "Cities with Pro-Dev Mayor {&rarr}", size(medlarge) placement(ne)) ///
        text(`y_max' -0.001 "{&larr} Cities with Non-Dev Mayor", size(medlarge) placement(nw) justification(right)) ///
        text(`y_lab_loc' -0.135 "Housing Permits Issued", size(medlarge) placement(ne) justification(right)) ///
        ysize(10) xsize(16)

    *-----------------------------------------------
    * Export figure
    *-----------------------------------------------
	* Display graph before exporting
	graph display `graph_name'

	* Attempt PDF export (capture to avoid stopping)
	graph export "${out_path}`c(dirsep)'figures`c(dirsep)'figure_3.pdf", as(pdf) replace

end

capture program drop run_table_5
program define run_table_5

	*------------------------------------------------------------
	* Globals: Table 5 values (numeric)
	*------------------------------------------------------------
	global T5_beta      2.044
	global T5_B         2124
	global T5_lambda    2.47
	global T5_Ndiff     39.37

	*------------------------------------------------------------
	* Compute share
	*------------------------------------------------------------
	scalar T5_share_num = ///
	    (${T5_beta} * ${T5_lambda} * ${T5_Ndiff}) / ${T5_B}

	* format as percentage with one decimal
	global T5_share : display %9.1f (100 * T5_share_num)
	global T5_share "${T5_share}\%"

	*------------------------------------------------------------
	* Create Table 5 (tabularx) LaTeX child document
	*------------------------------------------------------------
	local outfile "/Users/ruiyu/Library/CloudStorage/Dropbox/Research/FirmContribution/JMP/Submission/ReStat/Publication/restat_final/output/tables/table_5.tex"

	file open fh using "`outfile'", write replace text

	file write fh "\begin{tabularx}{\textwidth}" _n
	file write fh "{>{\raggedleft\arraybackslash}X" _n
	file write fh " >{\raggedleft\arraybackslash}p{0.5cm}" _n
	file write fh " >{\centering\arraybackslash}p{2.5cm}" _n
	file write fh " >{\centering\arraybackslash}p{1.5cm}}" _n
	file write fh "\hline" _n
	file write fh "\textbf{\footnotesize Description} &  & \textbf{\footnotesize Parameter} & \textbf{\footnotesize Estimate} \\\\" _n
	file write fh "\hline" _n

	file write fh "{\footnotesize Impact of Connection to Mayor on Developer Sales of New Housing Units}" ///
	              " &  & {\footnotesize \$\beta\$} & {\footnotesize ${T5_beta}} \\\\" _n
	file write fh _n

	file write fh "{\footnotesize Impact of Electing Pro-Development Mayor on Housing Permits}" ///
	              " &  & {\footnotesize \$B\$} & {\footnotesize ${T5_B}} \\\\" _n
	file write fh _n

	file write fh "{\footnotesize Factor Adjusting Sales of New Housing Units into New Housing Permits}" ///
	              " &  & {\footnotesize \$\lambda\$} & {\footnotesize ${T5_lambda}} \\\\" _n
	file write fh _n

	file write fh "{\footnotesize Number of Developers Connected to Pro-Development Mayor minus Opponent Candidate}" ///
	              " &  & {\footnotesize \$N^{DEV}-N^{NON}\$} & {\footnotesize ${T5_Ndiff}} \\\\" _n

	file write fh "\hline" _n

	file write fh "{\footnotesize Share of Housing Supply Impact Attributed to Favors from Pro-Development Mayors}" ///
	              " &  & {\footnotesize \$\frac{(N^{DEV}-N^{NON})\times\lambda\times\beta}{B}\$}" ///
	              " & {\footnotesize ${T5_share}} \\\\" _n

	file write fh "\hline" _n
	file write fh "\end{tabularx}" _n

	file close fh

	display as text "Table written to: `outfile'"



end

capture program drop calc_dep_mean
program define calc_dep_mean, rclass
args dep_var

	local base_dep_var = subinstr(subinstr(subinstr("`dep_var'", "fh_", "",.), "th_", "",.), "ch_", "", .)

	bys firm_id election_id: gegen tmp_max = max(e(sample))
	summ `base_dep_var' if tmp_max==1 & MV<0 & abs(MV)<=e(h_l) //& period==0 

	* Normalize to thousands
	if strpos("`dep_var'","th_") {
		local dep_mean = `r(mean)'/1000
	}
	else {
		local dep_mean = `r(mean)'
	}
	drop tmp*
	local dep_mean: di %10.2fc `dep_mean'
	return scalar out_mean = `dep_mean'

end

cap log close
main
cap log close
